
#pragma once // 防止头文件被重复包含
// 字符串处理的工具， 一些映射函数
#include <string>
#include <sys/socket.h>
#include "log.hpp"
#include <map>
class toll
{
public:
  static int gie_rows(int fd, std::string &str) // 获取一行
  {
    char c = 'A';
    while (c != '\n')
    {
      int i = recv(fd, &c, 1, 0);
      
      if (-1 == i)
      {
        return -1;
      }
      else if (i > 1)
      {
        return -1;
      }
      if (c == '\r')
      {
        recv(fd, &c, 1, MSG_PEEK); // 窥探数据，但不真正取走数据
        if (c == '\n')
        {
          recv(fd, &c, 1, 0); // 后面是\n就再读一次
        }
        c = '\n';
      }
      str += c;
    }
    return 1;
  }

  static void char_kv(std::string raw_str, std::string &k_str, std::string &v_str, std::string separator) // 字符串kv映射的处理函数
  {
    size_t pos = raw_str.find(separator);
    if (std::string::npos == pos)
    {
      LOG(ERROR, "请求报头解析出错, 并未找到请求报头的分隔符");
    }
    k_str = raw_str.substr(0, pos);
    v_str = raw_str.substr(pos + separator.size());
  }
};

static std::map<std::string, std::string> contentTypeMap = {
    {".txt", "text/plain"},
    {".html", "text/html"},
    {".htm", "text/html"},
    {".css", "text/css"},
    {".js", "text/javascript"},
    {".xml", "text/xml"},
    {".jpg", "image/jpeg"},
    {".jpeg", "image/jpeg"},
    {".gif", "image/gif"},
    {".png", "image/png"},
    {".mp3", "audio/mpeg"},
    {".mp4", "video/mp4"},
    {".json", "application/json"},
    {".pdf", "application/pdf"},
    {".doc", "application/msword"},
    {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
    {".xls", "application/vnd.ms-excel"},
    {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
    {".ppt", "application/vnd.ms-powerpoint"},
    {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
    {".zip", "application/zip"},
    // 注意：application/octet-stream 没有直接对应特定后缀，因为它用于未知或通用类型
};

static std::string file_type_kv(std::string k)
{
  auto it = contentTypeMap.find(k.c_str());
  if (it != contentTypeMap.end())
  {
    return it->second;
  }
  else
  {
    return "text/html";
  }
}

// 定义一个函数，使用std::map来映射HTTP状态码到其描述  
std::string state_kv(int code)  
{  
    // 创建一个map来存储HTTP状态码和它们的描述  
    // 这里的map是静态的，因此在整个程序中只会被初始化一次  
    static const std::map<int, std::string> http_status_codes = {  
        // 信息性状态码  
        { 200, "OK" }, // 请求成功  
        { 201, "Created" }, // 请求成功并创建了新的资源  
        { 202, "Accepted" }, // 请求已接受，但处理尚未完成  
        { 204, "No Content" }, // 请求成功，但没有返回任何内容  
  
        // 重定向状态码  
        { 301, "Moved Permanently" }, // 永久重定向  
        { 302, "Found" }, // 临时重定向  
        { 304, "Not Modified" }, // 资源未修改，使用缓存版本  
  
        // 客户端错误状态码  
        { 400, "Bad Request" }, // 客户端请求有语法错误  
        { 401, "Unauthorized" }, // 请求要求身份认证  
        { 403, "Forbidden" }, // 服务器理解请求但拒绝执行  
        { 404, "Not Found" }, // 请求的资源不存在  
        { 405, "Method Not Allowed" }, // 请求中使用的方法不被允许  
  
        // 服务器错误状态码  
        { 500, "Internal Server Error" }, // 服务器内部错误  
        { 501, "Not Implemented" }, // 服务器不支持请求的功能  
        { 502, "Bad Gateway" }, // 作为网关或代理的服务器从上游服务器收到无效响应  
        { 503, "Service Unavailable" }, // 服务器暂时无法处理请求  
        { 504, "Gateway Timeout" } // 作为网关或代理的服务器未及时从上游服务器收到请求  
    };  
  
    // 尝试在map中找到状态码  
    auto it = http_status_codes.find(code);  
    if (it != http_status_codes.end())  
    {  
        // 如果找到了，返回对应的描述  
        return it->second;  
    }  
    else  
    {  
        // 如果没有找到，返回一个默认的或错误的状态描述  
        return "Unknown Status Code";  
    }  
} 